﻿//----------------------------------------------------------------
// Desc: 
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2011-01-20
//
// Update Date : 
//
// Copyright (c) Fuel Game Engine (http://www.fge-engine.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once


class F2DParticle : public IFInstance< F2DParticle >
{
    FDECLARE_CLASS(F2DParticle)

protected:
    enum enumDefine
    {
        // 启动模式
        eStartMode_Normal = 0,          // 正常模式
        eStartMode_Exclusive_NoOver,    // 此类型唯一且不允许被新的覆盖
        eStartMode_Exclusive_Over,      // 此类型唯一且允许被新的覆盖
        eStartMode_Exclusive_AddTime,   // 此类型唯一且叠加新的时间

        // 精灵选择
        eSpriteSel_Random = 0,  // 随机
        eSpriteSel_CW,          // 从头顺序
        eSpriteSel_CCW,         // 从尾逆序
        eSpriteSel_Second_Rand, // 每秒随机一次

        // 旋转模式
        eRotate_Disable = 0,    // 不旋转
        eRotate_Line_CW,        // 线性顺时针旋转
        eRotate_Line_CCW,       // 线性逆时针旋转
        eRotate_Line_Random,    // 线性一次随机旋转
        eRotate_Variety,        // 随机变化旋转
        eRotate_Invariance,     // 恒定旋转
        eRotate_Once_Random,    // 启动时随机初始化旋转

        // 缩放模式
        eScale_Disable = 0,     // 不缩放
        eScale_Line_ZoomOut,    // 线性缩小
        eScale_Line_ZoomIn,     // 线性放大
        eScale_Line_Random,     // 线性一次随机缩放
        eScale_Variety,         // 随机变化缩放
        eScale_Invariance,      // 恒定缩放
        eScale_Once_Random,     // 启动时随机初始化缩放

        // 透明模式
        eAlpha_Invariance = 0,  // 恒定
        eAlpha_Fadeout,         // 渐隐
        eAlpha_Fadein,          // 渐显

        // 发射点模式
        eLaunchPoint_Up = 0,    // 从上边中间发射
        eLaunchPoint_Down,      // 从下边中间发射
        eLaunchPoint_Left,      // 从左边中间发射
        eLaunchPoint_Right,     // 从右边中间发射
        eLaunchPoint_Center,    // 从屏幕中央发射
        eLaunchPoint_Random_S,  // 单粒屏幕随机点
        eLaunchPoint_Random_B,  // 群集屏幕随机点

        // 发射类型
        eLaunchType_Normal = 0, // 按频率发射
        eLaunchType_SecondOnce, // 每秒齐发
        eLaunchType_Once,       // 一次性发射由频率值所填数量

        // 轨迹模式
        eTrack_Nothing = 0,     // 无轨迹
        eTrack_Fadeout,         // 轨迹点普通渐隐
        eTrack_Fadeout_Rotate,  // 轨迹点渐隐+旋转
        eTrack_Fadeout_Scale,   // 轨迹点渐隐+缩小
        eTrack_Fadeout_RS,      // 轨迹点渐隐+旋转+缩小
        eTrack_Scale,           // 渐渐缩小不渐隐

        // 旋转方向
        eRotateDir_CW = 0,      // 顺时针
        eRotateDir_CCW,         // 逆时针
        eRotateDir_Nothing,     // 不旋转

        // 缩放方向
        eScaleDir_ZoomOut = 0,  // 缩小
        eScaleDir_ZoomIn,       // 放大
        eScaleDir_Nothing,      // 不缩放

        // 特效类型
        eEType_Petal_Little = 0,    // 花瓣(少)效果
        eEType_Petal_Much,          // 花瓣(多)效果
        eEType_Salute_Sky_Rain,     // 天雨
        eEType_Salute_Single_Point, // 烟花单色点
        eEType_Salute_Mult_Point,   // 烟花混色点

        eEType_Max,
        eEType_Begin = eEType_Petal_Little,
    };
    // 发射器参数
    struct EFC_Parameter
    {
        typedef_vector(IFSpriteObject*, _psprite_obj);

        FString szPicture;      // 资源路径
        fv_psprite_obj vSprite; // 资源精灵数据
        BYTE nStartMode;        // 启动模式
        WORD nSpriteWidth;      // 单精灵宽度
        WORD nSpriteHeight;     // 单精灵高度
        DWORD nSpriteLifeMin;   // 单精灵最小生命长度: 毫秒
        DWORD nSpriteLifeMax;   // 单精灵最大生命长度: 毫秒
        BYTE nSpriteSelect;     // 精灵图片选择
        BYTE nSpriteHighLight;  // 精灵开启高光混合
        BYTE nRotateMode;       // 旋转模式
        float fRotateSpeed;     // 旋转速度
        float fRotateSpeedSwing;// 旋转速度振幅
        BYTE nScaleMode;        // 缩放模式
        float fScaleSpeed;      // 旋转速度
        float fScaleSpeedSwing; // 旋转速度振幅
        float fStartSpeed;      // 初始速度
        float fStartSpeedSwing; // 初始速度振幅
        float fGravity;         // 垂直重力
        float fGravitySwing;    // 垂直重力振幅
        float fWindPower;       // 水平风力
        float fWindPowerSwing;  // 水平风力振幅
        BYTE nAlphaMode;        // 透明模式
        float fAlphaStart;      // 透明起始值
        BYTE nLaunchPointMode;  // 发射点模式
        int nLaunchPointWidth;  // 发射点边线宽度
        WORD nLaunchAngle;      // 发射角度[0->360]度
        DWORD nLaunchFreqMin;   // 发射频率 (m->n)个/秒 (m>0, n>0, n>m)
        DWORD nLaunchFreqMax;   // 发射频率 (m->n)个/秒 (m>0, n>0, n>m)
        BYTE nLaunchType;       // 发射类型
        DWORD nTimeFrequency;   // 每秒等于多少毫秒
        BYTE nTrackMode;        // 轨迹模式
        DWORD nTrackFreq;       // 轨迹产生频率: 每n毫秒/1个
        DWORD nTrackLife;       // 每个轨迹生命时长: 毫秒
        float fTrackGravityInfl;// 轨迹受重力影响度
        float fTrackWindPowerInfl;// 轨迹受风力影响度
        float fTrackScaleInfl;  // 轨迹缩放继承率
        float fTrackAlphaInfl;  // 轨迹透明继承率

        FIDTEXTURE nTextureID;  // 资源贴图ID

        EFC_Parameter()
            :nTextureID(eCD_ErrorTex)
            ,nLaunchFreqMin(1)
            ,nLaunchFreqMax(1)
        {}
        bool IsValid(){ return nTextureID != eCD_ErrorTex; }
        void Clear(){ nTextureID=eCD_ErrorTex; }
    };
    struct EFC_Emitter;
    struct EFC_Particle;
    struct EFC_Track
    {
        IFSpriteObject* pSprite;
        float fScale;
        float fRotate;
        float fAlpha;
        FVECTOR2 fPosition;
        DWORD nBirthTime;
        DWORD nDeathTime;
        EFC_Track(DWORD nCurTime, EFC_Particle* part, EFC_Parameter* param);
    };
    typedef_vector(EFC_Track, _track);
    // 单个粒子
    struct EFC_Particle : public IFMemObject
    {
        FDECLARE_CLASS(EFC_Particle)

        DWORD nBirthTime;
        DWORD nUpdateTime;      // 上次更新时间
        DWORD nDeathTime;       // 死亡时间
        DWORD nTrackTime;       // 上次产生轨迹时间
        IFSpriteObject* pSprite;// 精灵地址
        FVECTOR2 fBirthPosition;  // 出生位置
        FVECTOR2 fCurDir;         // 当前运动方向
        FVECTOR2 fCurPosition;    // 当前位置
        float fMoveSpeed;       // 运动速度
        float fCurRotate;       // 当前旋转度
        float fCurScale;        // 当前缩放度
        float fAlpha;           // 当前透明度
        float fGravityInfl;     // 垂直重力影响值
        float fWindPowerInfl;   // 水平风力影响值
        BYTE nRotateDir;        // 当前旋转方向
        float fRotateInfl;      // 旋转影响值
        BYTE nScaleDir;         // 当前缩放方向
        float fScaleInfl;       // 缩放影响值
        fv_track vTrack;        // 轨迹数据

        void Render(DWORD nCurTime, EFC_Emitter* etr);
    };
    typedef_vector(EFC_Particle*, _pparticle);
    // 发射器
    struct EFC_Emitter : public IFMemObject
    {
        int nType;                      // 特效类型
        EFC_Parameter* param;           // 发射器参数地址
        DWORD nStartTime, nEndTime;     // 发射器启动时间，结束时间
        DWORD nSecondCounter;           // 时钟计数
        FV_DWORD vSecondBirthTime;      // 当前秒出生时间表
        fv_pparticle vParticle;         // 活动中的粒子表
        FVECTOR2 vCurRandomPosition;      // 当前帧随机点
        IFSpriteObject* pCurRandomSprite;// 当前帧随机精灵

        EFC_Emitter(int type){ nType = type; param = 0; pCurRandomSprite = 0; }
        IFSpriteObject* RandomSprite();
        IFSpriteObject* GetSprite(IFSpriteObject* cur, bool prev);

        FDECLARE_CLASS(EFC_Emitter)
    };

public:
    F2DParticle();
    ~F2DParticle();
    void Init(IFEngine* fge, const TCHAR* config_file, bool only_param = false);
    void Release(IFEngine* fge);
    void ClearData();
    void Play(int type, DWORD length = 1000);
    void Update(IFEngine* fge);
    void Render(IFEngine* fge);

protected:
    void LoadConfig(IFEngine* fge, EFC_Parameter& param, IFINI* reader, bool only_param);
    void BrithParticle(IFEngine* fge, DWORD nCurTime, EFC_Emitter* pEmtr, FVECTOR2* param1, IFSpriteObject* param2);
    bool KillParticle(DWORD nCurTime, EFC_Emitter* pEmtr, size_t nIndex, bool force_kill);
    void UpdateParticle(DWORD nCurTime, EFC_Emitter* pEmtr, size_t nIndex);
    EFC_Emitter* FindEmitter_first(int type);

protected:
    typedef_vector(EFC_Emitter*, _ppemitter);
    EFC_Parameter nEFCParam[eEType_Max];
    fv_ppemitter vEmitterVec;
};